﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Reflection;
using System.Windows;
using OutlookTags.Native;
using OutlookTags.Helpers;
using System.Globalization;
using OutlookTags.Controls;

namespace OutlookTags
{
    public class TagsCommandBar : ITagsView
    {
        Office.CommandBar TagsBar { get; set; }
        Office.CommandBarButton ArchiveButton { get; set; }
        CommandBarEditAutocomplete TagsEdit { get; set; }
        Office.CommandBarButton SearchButton { get; set; }
        IList<DisplayTag> DisplayTags { get; set; }
        Dictionary<string, DisplayTag> TagsHash = new Dictionary<string, DisplayTag>();
        bool _showTags = false;
        TagsController Controller{get;set;}

        public void Initialize(TagsController controller)
        {
            Outlook.Application application = controller.Application;
            DisplayTags = new List<DisplayTag>();
            var commandBars = application.ActiveExplorer().CommandBars;
            Controller = controller;

            TagsBar = commandBars.Add("Tags", Office.MsoBarPosition.msoBarTop, false, true);// TODO: get strings from resources
          
            //setup archive button
            ArchiveButton = (Office.CommandBarButton)TagsBar.Controls.Add(Office.MsoControlType.msoControlButton,
                1, "", Missing.Value, true);
            ArchiveButton.Caption = "&1.Archive";
            ArchiveButton.Visible = true;
            ArchiveButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(archiveButton_Click);

            //setup tag text box
            var edtiControl = TagsBar.Controls.Add(Office.MsoControlType.msoControlEdit, 
                1, "", Missing.Value, true);

            edtiControl.Visible = true;
            edtiControl.Width = 256;
            
            //Setup tags button
            SearchButton = (Office.CommandBarButton)TagsBar.Controls.Add(Office.MsoControlType.msoControlButton,
                Missing.Value, Missing.Value, Missing.Value, true);
            SearchButton.Caption = "Search";
            //searchButton.Controls.Add(Office.MsoControlType.msoControlEdit, 1, Missing.Value, Missing.Value, true);
            SearchButton.Tag = "tag search";
            SearchButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(searchButton_Click);
            

            SearchButton.Visible = true;           
             

            TagsBar.Visible = true;
            TagsEdit = new CommandBarEditAutocomplete(edtiControl);
            //TagsEdit.KeyUp += new System.Windows.Forms.KeyEventHandler(TagsEdit_KeyUp);
            TagsEdit.Char += new EventHandler(TagsEdit_Char);
            TagsEdit.Enter += new EventHandler(TagsEdit_Enter);
            TagsEdit.Leave += new EventHandler(TagsEdit_Leave);
        }

        void TagsEdit_Char(object sender, EventArgs e)
        {
            FormatTags();
        }

        void searchButton_Click(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            MessageBox.Show(string.Format("{0}x{1}", SearchButton.Left, SearchButton.Top));
        }

        void TagsEdit_Leave(object sender, EventArgs e)
        {
            string text = TagsEdit.GetText();
            
            Controller.ApplyTagsForCurrentItem(text);
            if (text.Length == 0 && !_showTags)
            {
                TagsEdit.Text = "Type here to Tag";
            }
        }

        void TagsEdit_Enter(object sender, EventArgs e)
        {
            if (!_showTags)
                TagsEdit.Text = "";
        }

        void TagsEdit_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            FormatTags();
        }

        private void FormatTags()
        {
            CHARRANGE range = TagsEdit.GetSelectRange();
            var text = TextFormatHelper.ConvertTagsToRtf(TagsEdit.Text, TagsHash);
            TagsEdit.WriteRtf(text);
            TagsEdit.SetSelectRange(range);
        }

        void archiveButton_Click(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            Controller.ArchiveSelection();
        }

        #region ITagsView Members
        
        public void UpdateDisplayTags(IList<DisplayTag> displayTags)
        {
            DisplayTags = displayTags;
            TagsHash = new Dictionary<string, DisplayTag>();
            TagsEdit.AutoCompleteSource.Clear();
            TagsEdit.AutoCompleteSource.Add("");
            foreach (var tag in displayTags)
            {
                TagsHash[tag.Name.Trim().ToUpper()] = tag;
                TagsEdit.AutoCompleteSource.Add(tag.Name);
            }
        }

        public void UpdateSelection(IList<DisplayTag> displayTags)
        {
            if (TagsEdit.Focused)
                return;

            var separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
            StringBuilder bdr = new StringBuilder();
            if (displayTags.Count > 0)
            {
                bdr.Append(displayTags[0].Name);
                foreach (var tag in displayTags.Skip(1))
                {
                    bdr.Append(separator);
                    bdr.Append(" ");
                    bdr.Append(tag.Name);
                }
            }
            _showTags = displayTags.Count != 0;
            var str =  bdr.ToString();
            if (str == "")
                TagsEdit.Text = "Type here to Tag";
            else
            {
                TagsEdit.Text = str;
                FormatTags();
            }
        }

        public void SetArchiveEnabled(bool enabled)
        {
            ArchiveButton.Enabled = enabled;
        }

        #endregion
    }
}
